/*
 * battery电池电量检测
 */
#include "head\battery.h"
#include "head\MCU.h"
#include "head\DebugTool.h"

void battery_Init()
{
    /*
     * 配置IIC复用引脚
     */
    GPIO_setAsPeripheralModuleFunctionInputPin(
        BATTERY_IIC_PORT,
        BATTERY_IIC_PIN_SDA + BATTERY_IIC_PIN_SCL
        );

    /*
     * 初始化IIC主模式
     */
    USCI_B_I2C_initMasterParam param = {0};
    param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = UCS_getSMCLK(); //返回一个u32，此时SMCLK的时钟频率
    param.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS; //选择传输速度，有100和400两种选择
    USCI_B_I2C_initMaster(BATTERY_IIC_BASE, &param);

    /*
     * 指定从机地址
     */
    USCI_B_I2C_setSlaveAddress(BATTERY_IIC_BASE,BATTERY_ADDR);

    USCI_B_I2C_enable(BATTERY_IIC_BASE);
    __enable_interrupt();
    /*
     * 初始化寄存器参数
     */
        battery_Write_Registers(0x00,0x2f);
        battery_Write_Registers(0x03,0x70);
        battery_Write_Registers(0x02,0x9D);
}

void battery_Write_Registers(uint8_t reg, uint8_t data)
{
    uint8_t Timeing = 6;
    //Enable transmit Interrupt
    USCI_B_I2C_clearInterrupt(BATTERY_IIC_BASE,
        USCI_B_I2C_TRANSMIT_INTERRUPT | USCI_B_I2C_RECEIVE_INTERRUPT);//清除中断标志，及 UCBxIFG 置0
    USCI_B_I2C_enableInterrupt(BATTERY_IIC_BASE,
        USCI_B_I2C_TRANSMIT_INTERRUPT | USCI_B_I2C_RECEIVE_INTERRUPT);//设置中断使能，及 UCBxIE 置1

    //Delay between each transaction
    __delay_cycles(50);

    BatteryTxCount = 2-1;                 //-1表示不发送结束信号

    BatteryTxDataBuff[0] = reg;               //将要发送的数据1，寄存器地址
    BatteryTxDataBuff[1] = data;              //将要发送的数据2，寄存器数值
    pBatteryTxData = (uint8_t *)BatteryTxDataBuff;//指向将要发送的数据的开头

    BatteryRxCount = 0;                         //将要接收的数据长度
//    pBatteryRxData = (uint8_t *)buf;          //指向存放将要接收的数据的地址开头

    USCI_B_I2C_masterSendMultiByteStart(BATTERY_IIC_BASE,*pBatteryTxData++);//发送S、AD+W与第一个字节（陀螺仪的寄存器地址）
    //等待停止信号发送完毕
    do{
        __delay_cycles(MSP430_FREQUENCY/2);
        Timeing--;
        if(Timeing == 0)
        {
            printfDBG("batter write i2c false",22);
        }
    }
    while(BatteryTxCount != -1);
}

void battery_Read_Len(uint8_t reg, uint8_t* buf, uint8_t len)
{
    uint8_t Timeing = 6;
    //Enable transmit Interrupt
    USCI_B_I2C_clearInterrupt(BATTERY_IIC_BASE,
        USCI_B_I2C_TRANSMIT_INTERRUPT | USCI_B_I2C_RECEIVE_INTERRUPT);//清除中断标志，及 UCBxIFG 置0
    USCI_B_I2C_enableInterrupt(BATTERY_IIC_BASE,
        USCI_B_I2C_TRANSMIT_INTERRUPT | USCI_B_I2C_RECEIVE_INTERRUPT);//设置中断使能，及 UCBxIE 置1

    //Delay between each transaction
    __delay_cycles(50);

    BatteryTxCount = -2;                 //-2表示不发送结束信号，直接进入接收模式
    if(len == 1)
    {
        BatteryTxCount = -3;        //只接受一个字节的数据需要另外操作
    }

    BatteryTxDataBuff[0] = reg;               //将要发送的数据1，寄存器地址
    pBatteryTxData = (uint8_t *)BatteryTxDataBuff;//指向将要发送的数据的开头

    BatteryRxCount = len;                   //将要接收的数据长度
    pBatteryRxData = (uint8_t *)buf;          //指向存放将要接收的数据的地址开头

    //Initiate start and send first character
    USCI_B_I2C_masterSendMultiByteStart(BATTERY_IIC_BASE,*pBatteryTxData);

    do{
        __delay_cycles(MSP430_FREQUENCY/2);
        Timeing--;
        if(Timeing == 0)
        {
            __no_operation();
        }
    }
    while(BatteryRxCount!=0);
    __no_operation();
}

void battery_getVoltage(uint8_t *buf)
{
    uint8_t data;
    battery_Write_Registers(0x02,0x9D);
    battery_Read_Len(0x0E,&data,1);
    *buf = (uint8_t)((float)data*0.2+23.04);
}

//******************************************************************************
//
//This is the USCI_B2 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B2_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B2_VECTOR)))
#endif
void BATTERY_USCI_B2_ISR (void)
{
    switch (__even_in_range(UCB2IV,12)){
        case USCI_I2C_UCTXIFG:
        {
            if(BatteryTxCount == -3)
            {
                USCI_B_I2C_clearInterrupt(BATTERY_IIC_BASE,USCI_B_I2C_TRANSMIT_INTERRUPT);
                USCI_B_I2C_setMode(BATTERY_IIC_BASE,USCI_B_I2C_RECEIVE_MODE);
                USCI_B_I2C_masterReceiveSingleStart(BATTERY_IIC_BASE);
            }
            else if(BatteryTxCount == -2)
            {
                USCI_B_I2C_clearInterrupt(BATTERY_IIC_BASE,USCI_B_I2C_TRANSMIT_INTERRUPT);
                USCI_B_I2C_setMode(BATTERY_IIC_BASE,USCI_B_I2C_RECEIVE_MODE);
                USCI_B_I2C_masterReceiveMultiByteStart(BATTERY_IIC_BASE);
            }
            //Check TX byte counter
            else if (BatteryTxCount > 0)
            {
                //Initiate send of character from Master to Sla
                USCI_B_I2C_masterSendMultiByteNext(BATTERY_IIC_BASE,*pBatteryTxData++);
                //Increment TX byte counter
                BatteryTxCount--;
            }
            else
            {
                //Initiate stop only
                USCI_B_I2C_masterSendMultiByteStop(BATTERY_IIC_BASE);
                //Clear master interrupt status
                USCI_B_I2C_clearInterrupt(BATTERY_IIC_BASE,USCI_B_I2C_TRANSMIT_INTERRUPT);
                BatteryTxCount--;
            }
            break;
        }
        case USCI_I2C_UCRXIFG:
        {
            BatteryRxCount--;
            if(BatteryTxCount)
            {
                *pBatteryRxData = USCI_B_I2C_masterReceiveSingle(BATTERY_IIC_BASE);
                break;
            }
            else if (BatteryRxCount)
            {
                if (BatteryRxCount == 1)
                {
                    //Initiate end of reception -> Receive byte with NAK
                    *pBatteryRxData++ = USCI_B_I2C_masterReceiveMultiByteFinish(BATTERY_IIC_BASE);
                }
                else
                {
                    //Keep receiving one byte at a time
                    *pBatteryRxData++ = USCI_B_I2C_masterReceiveMultiByteNext(BATTERY_IIC_BASE);
                }
            }
            else
            {
                //Receive last byte
                *pBatteryRxData++ = USCI_B_I2C_masterReceiveMultiByteNext(BATTERY_IIC_BASE);
            }
                break;
        }
        default:break;
    }
}
